#!/usr/bin/python

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.lib.colors import black, white, gray, lightgrey,  darkgray,  red 
from reportlab.lib.pagesizes import letter
from reportlab.platypus.tables import LINECAPS

import re
import json
from sys import argv

from Weapon import Weapon

pdfmetrics.registerFont(TTFont('LS_B', 'fonts/LiberationSans-Bold.ttf'))
pdfmetrics.registerFont(TTFont('LS_BI', 'fonts/LiberationSans-BoldItalic.ttf'))
pdfmetrics.registerFont(TTFont('LS_I', 'fonts/LiberationSans-Italic.ttf'))
pdfmetrics.registerFont(TTFont('LS', 'fonts/LiberationSans-Regular.ttf'))
pdfmetrics.registerFont(TTFont('RET', 'fonts/Retriga.ttf'))

''' 
    Parse the input .csv file as a list of weapons (one per line)
    and construct a data object for later consumption
'''
def parseList(srcF):
    weapons = {}
    header = ""

    pattern = re.compile("^[a-zA-Z]+$")
    for rawline in srcF:
        line = rawline.strip()
        if line == "": 
            continue
        tmp = line.replace(",", "")
        if tmp == "":
            continue
        if pattern.match(tmp):
            header = tmp
            if header not in weapons:
                weapons[header] = []
            print "Found header: %s" % header
            continue
            
        print "Weapon: [%s]" % line
        weapon = Weapon(line)
        print "Adding to header: [%s]" % header
        weapons[header].append(weapon)
        
    return weapons

'''
    Actually draw the chart now
'''
def writeChart(category, weapons, c, lineY, config):
    if (len(weapons) == 0):
        return

    if (lineY == 0): 
        lineY = letter[1] - config["margin"]
    else:
        lineY = lineY - config["categoryFontSize"]

    # Estimate if we should skip a page
    # 1.3 is our guesstimate for spacing, etc
    estNumPoints = (len(weapons) * config["fontSize"] * 1.3)
    print "Estimated points is %2.3f, delta is %2.3f" % (estNumPoints, (lineY - estNumPoints))
    if ((lineY - estNumPoints) <= 0):
        c.showPage()
        lineY = letter[1] - config["margin"]
    

    # Write the category & header
    c.setFont("RET", config["categoryFontSize"])
    c.drawString(config["margin"], lineY, category)
    c.line(config["margin"], lineY-2, letter[0] - config["margin"], lineY - 2);
    lineY = lineY - config["categoryFontSize"]

    lineY = writeHeaderLine(c, lineY, config)

    numPoints = config["maxPoints"]
    lastCode = ""
    for weapon in weapons:
    
        if category != "MELEE" and category != "THROWN" and category != "INFANTRY":   
            code = weapon.code
            #print "raw code is: [%s]" % (code),
            # If the weapon starts with V, take everything after 2
            code = code[1:]

            if not code == lastCode:
                #print "Changed weapons, skipping a space"
                numPoints = numPoints - 4
                lineY = lineY - 4
            lastCode = code
        else:
            lineY = lineY - 4

        #print "Weapon is %s" % weapon
        writeWeaponLine(c, weapon, lineY, config)
        lineY = lineY - config["fontSize"]
        numPoints = numPoints - config["fontSize"]

    return lineY 
        

def writeHeaderLine(canvas, y, config):
    marginX = config["margin"]
    fontSize = config["fontSize"]

    canvas.setStrokeColor(gray)
    canvas.setFillColor(gray)
    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 10, y, "CODE")
    canvas.drawString(marginX + 60, y, "HGB")

    canvas.drawRightString(marginX + 125, y, "RNG")

    canvas.drawRightString(marginX + 160, y, "BD")
    canvas.drawString(marginX + 165, y, "DM")

    canvas.drawString(marginX + 200, y, "TRAITS")

    canvas.line(marginX + 6, y-2, letter[0] - marginX, y-2)

    canvas.setStrokeColor(black)
    canvas.setFillColor(black)
    return y-8


def writeWeaponLine(canvas, weapon, y, config):
    marginX = config["margin"]
    fontSize = config["fontSize"]

    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 10, y, weapon.code)

    canvas.setFont("LS", fontSize)
    canvas.drawString(marginX + 60, y, weapon.blitzCode)

    canvas.setFont("LS", fontSize)
    canvas.drawRightString(marginX + 125, y, "%s\"" % (weapon.range))

    canvas.drawRightString(marginX + 158, y, weapon.baseDamage)

    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 167, y, "x%s" % (weapon.damageMulti))

    canvas.setFont("LS_I", fontSize)
    canvas.drawString(marginX + 200, y, weapon.traits)

if __name__ == '__main__':

    src = "weapons.csv"
    if (len(argv) > 1):
        src = argv[1]
    srcF = open(src, 'r')
    weapons = parseList(srcF); 
    srcF.close()

    c = canvas.Canvas("weapons.pdf", pagesize=letter)
    c.setStrokeColor(black)
    config = {
        "margin" :20,
        "fontSize" : 10,
        "categoryFontSize" : 16,
        "maxPoints" : int((letter[1] - 20 * 2))
    }
    lineY = 0
    categories = ["CANNONS", "ASSAULT", "BEAMS", "MISSILES", "INDIRECT", "THROWN", "MELEE", "INFANTRY"]
    for cat in categories:
        print "Category is [%s]" % cat
        lineY = writeChart(cat, weapons[cat], c, lineY, config)
        print "New LineY = %i" % lineY
    c.save() 


